8 static char text
[50001];
9 static unsigned int sa
[50000];
10 static unsigned int rank1
[50000]={0};
11 static unsigned int rank2
[50000]={0};
14 static long long total
;
15 static unsigned cuantos
;
18 int bucket
, aux
, desde
, actual
;
20 unsigned int* proximo
;
26 const unsigned int* rank
;
27 Comparador(const int j
,const unsigned int* vrank
): K(j
), rank(vrank
) {};
29 bool inline operator()(const int i
, const int j
) const {
30 return clave(i
) < clave(j
);
33 int inline clave(const int i
) const {
34 return (i
+K
< N
? rank
[i
+K
]+1 : 0);
39 int main(int argc
, const char *argv
[]) {
41 scanf("%d", &cuantos
);
43 for (int c
= 0; c
< cuantos
; c
++) {
49 for (int i
= 0; i
< N
; i
++) {
55 sort(sa
, sa
+N
, Comparador(0, rank1
));
60 for (int t
= 1; t
< N
; t
++) {
61 if (text
[sa
[t
-1]] == text
[sa
[t
]]) {
62 rank1
[sa
[t
]] = bucket
;
65 rank1
[sa
[t
]] = bucket
;
73 for (int K
= 1; K
< N
; K
*= 2) {
76 Comparador
comparador(K
,ahora
);
78 while (actual
< N
&& ahora
[sa
[actual
]] == ahora
[sa
[actual
-1]]) {
81 if (actual
> desde
+1) {
82 sort(sa
+desde
, sa
+actual
, comparador
);
92 for (int t
= 1; t
< N
; t
++) {
93 if (ahora
[sa
[t
]] == aux
&& comparador
.clave(sa
[t
-1]) == comparador
.clave(sa
[t
])) {
94 proximo
[sa
[t
]] = bucket
;
99 proximo
[sa
[t
]] = bucket
;
103 swap(ahora
, proximo
);
111 for (int i
= 0; i
< N
; i
++) {
115 if (ahora
[i
] == N
-1) {
116 total
+= N
+ 1 - sa
[N
-1];
120 int j
= sa
[ahora
[i
]+1];
121 while (text
[i
+k
] == text
[j
+k
]) k
++;
122 total
+= N
- k
- sa
[ahora
[i
]];
125 // El codigo de arriba pone un -1 en la
126 // fila final del LCP en lugar de un 0 en la primera,
127 // asi que hay que restarlo ahora.
130 printf("%lld\n", total
);